/**
  ******************************************************************************
  * @file           : mem_leak1.cpp
  * @author         : JarryLi
  * @brief          : None
  * @date           : 2024/10/14 9:23
  ******************************************************************************
  */

#include <stdio.h>
#include <dlfcn.h>
#include <link.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>

#define _GNU_SOURCE // __FILE__    __LINE__

#define BUFF_SIZE 128

int flag = 1;

#if 1
void* _malloc(size_t size, const char* filename, const int line)
{
    void* p = malloc(size);

    if (flag)
    {
        char buff[BUFF_SIZE] = { 0 };
        snprintf(buff, BUFF_SIZE, "./file/%p.mem", p);

        FILE* fp = fopen(buff, "w");
        if (!fp)
        {
            free(p);
            return NULL;
        }

        fprintf(fp, "[+]%s: %d, addr: %p, size: %ld\n", filename, line, p, size);
        printf("[+]%s: %d, addr: %p, size: %ld\n", filename, line, p, size);

        // 写入文本到文件，需要刷新，fclose的时候会刷新
        fflush(fp);
        fclose(fp);
    }

    // printf("_malloc: %p, size: %ld\n", p, size);

    return p;
}

void _free(void* ptr)
{
    // printf("_free: %p\n", ptr);
    if (flag)
    {
        char buff[BUFF_SIZE] = { 0 };
        snprintf(buff, BUFF_SIZE, "./file/%p.mem", ptr);

        // unlink删除文件的软连接
        // 如果文件最后的硬链接是这个，那么文件直接会被删除
        if (unlink(buff) < 0)
        {
            printf("double free: %p\n", ptr);
            return;
        }
    }

    return free(ptr);
}

// 注意define放的位置
#define malloc(size) _malloc(size, __FILE__, __LINE__)
#define free(size) _free(size)

#endif

int main()
{
    void* p1 = malloc(10);
    void* p2 = malloc(15);
    void* p3 = malloc(5);

    free(p1);
    free(p2);
    return 0;
}
